package com.huaxin.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.device.dto.ResponseCode;
import com.huaxin.device.dto.ResponseResult;
import com.huaxin.device.dto.enums.AlarmType;
import com.huaxin.device.dto.enums.schemes.SchemaValidator;
import com.huaxin.device.dto.request.AlarmThresholdRuleCreateReqDTO;
import com.huaxin.device.dto.request.AlarmThresholdRulePageListReqDTO;
import com.huaxin.device.dto.request.AlarmThresholdRuleUpdateReqDTO;
import com.huaxin.device.mapper.AlarmThresholdRuleMapper;
import com.huaxin.device.mapping.AlarmThresholdRuleMapping;
import com.huaxin.device.models.AlarmThresholdRule;
import com.huaxin.device.service.AlarmThresholdRuleService;
import lombok.RequiredArgsConstructor;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.webjars.NotFoundException;

import java.util.List;

import static org.springframework.util.StringUtils.hasText;

@Service
@RequiredArgsConstructor
public class AlarmThresholdRuleServiceImpl extends ServiceImpl<AlarmThresholdRuleMapper, AlarmThresholdRule> implements AlarmThresholdRuleService {
    private final ApplicationContext applicationContext;
    private final AlarmThresholdRuleMapping mapping;

    @Override
    public ResponseResult<AlarmThresholdRule> create(AlarmThresholdRuleCreateReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }

        AlarmThresholdRule entity = mapping.toEntity(in);
        if (!this.save(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "添加失败，请稍后再试！", null);
        }
        AlarmThresholdRule created = this.getById(entity.getId());
        return ResponseResult.ok(created);
    }

    @Override
    public AlarmThresholdRule getByRuleId(String id) {
        if (StringUtils.isBlank(id)) {
            throw new IllegalArgumentException("ID不能为空");
        }
        AlarmThresholdRule entity = this.getById(id);
        if (entity == null) {
            throw new NotFoundException("报警阈值规则不存在");
        }
        return entity;
    }

    @Override
    public ResponseResult<String> update(AlarmThresholdRuleUpdateReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }

        AlarmThresholdRule entity = this.getByRuleId(in.getId());
        mapping.updateEntity(in, entity);
        if (!this.updateById(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "更新失败，请稍后再试！", null);
        }
        return ResponseResult.ok("更新成功");
    }

    @Override
    public ResponseResult<String> delete(String id) {
        AlarmThresholdRule entity = this.getByRuleId(id);
        // 启用状态不允许删除
        if (entity.getIsEnabled()) {
            return ResponseResult.failure(ResponseCode.CUSTOM_BUSINESS_ERROR, "启用状态不允许删除", null);
        }
        boolean removed = this.applicationContext.getBean(AlarmThresholdRuleService.class).removeById(id);
        if (!removed) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "删除失败，请稍后重试", null);
        }
        return ResponseResult.ok("删除成功！");
    }

    @Override
    public ResponseResult<String> enable(String id) {
        AlarmThresholdRule entity = this.getByRuleId(id);
        entity.setIsEnabled(true);
        if (!this.updateById(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "启用失败，请稍后再试！", null);
        }
        return ResponseResult.ok("启用成功");
    }

    @Override
    public ResponseResult<String> disable(String id) {
        AlarmThresholdRule entity = this.getByRuleId(id);
        entity.setIsEnabled(false);
        if (!this.updateById(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "禁用失败，请稍后再试！", null);
        }
        return ResponseResult.ok("禁用成功！");
    }

    @Override
    public ResponseResult<IPage<AlarmThresholdRule>> pageQuery(AlarmThresholdRulePageListReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }

        IPage<AlarmThresholdRule> page = new Page<>(in.getPageNum(), in.getPageSize());
        LambdaQueryWrapper<AlarmThresholdRule> wrapper = new LambdaQueryWrapper<>();

        // 按启用状态过滤
        if (in.getIsEnabled() != null) {
            wrapper.eq(AlarmThresholdRule::getIsEnabled, in.getIsEnabled());
        }

        // 按报警类型过滤
        if (hasText(in.getAlarmType())) {
            wrapper.eq(AlarmThresholdRule::getAlarmType, AlarmType.of(in.getAlarmType()));
        }

        // 按报警等级过滤
        if (in.getAlarmLevel() != null) {
            wrapper.eq(AlarmThresholdRule::getAlarmLevel, in.getAlarmLevel());
        }

        // 按报警模板过滤
        if (hasText(in.getTemplateId())) {
            wrapper.eq(AlarmThresholdRule::getTemplateId, in.getTemplateId());
        }

        // 关键字搜索：规则描述
        if (hasText(in.getKeyword())) {
            wrapper.like(AlarmThresholdRule::getDescription, in.getKeyword());
        }

        // 按创建时间排序
        wrapper.orderByDesc(AlarmThresholdRule::getCreatedAt);

        IPage<AlarmThresholdRule> resultPage = this.page(page, wrapper);
        return ResponseResult.ok(resultPage);
    }

    /*
     * 校验监控字段
     * @param metricField 监控字段，格式为：表名.字段名
     */
    private boolean validateMetricField(String metricField) {
        if (StringUtils.isBlank(metricField)) {
            return false;
        }

        if (!metricField.contains(".")) {
            return false;
        }

        String[] metricFieldArr = metricField.split("\\.");
        if (metricFieldArr.length != 2) {
            return false;
        }
        if (!hasText(metricFieldArr[0]) && hasText(metricFieldArr[1])) {
            return false;
        }

        String tableName = metricFieldArr[0];
        String fieldName = metricFieldArr[1];
        SchemaValidator.ValidationResult validationResult = SchemaValidator.validateTableAndField(tableName, fieldName);
        return validationResult.isValid();
    }

    @Override
    public List<AlarmThresholdRule> getByTemplateId(String templateId) {
        LambdaQueryWrapper<AlarmThresholdRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AlarmThresholdRule::getTemplateId, templateId);
        return this.list(wrapper);
    }
}
